//  -----------------------------------------------------------------------------------------------//
//   This file is part of SvnExternalUpdater                                                               //
//   Copyright (C)2008 Romain Verdier ( romain@codingly.com )                                      //
//                                                                                                 //
//   This program is free software; you can redistribute it and/or modify it under the terms       //
//   of the GNU General Public License as published by the Free Software Foundation; either        //
//   version 2 of the License, or (at your option) any later version. This program is distributed  //
//   in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied        //
//   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public  //
//   License for more details.                                                                     //
//                                                                                                 //
//   You should have received a copy of the GNU General Public License along with this program; if //
//   not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. or  //
//   see http://www.fsf.org/licensing/licenses/gpl.html                                            //
//  -----------------------------------------------------------------------------------------------//
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Codingly.SvnExternalUpdater.Core.EventHandlers;
using Codingly.SvnExternalUpdater.Core.Model;

namespace Codingly.SvnExternalUpdater.Core
{
	internal class Project : IProject, IRemoteConnected
	{
		private readonly List<IExternal> externals = new List<IExternal>();
		private readonly string name;
		private readonly string path;
		private readonly IRemoteFolder remoteFolder;

		private string externalPropertyValue;

		private bool isUpToDate;
		private long localRevision;

		public Project(string path, IRemoteFolder remoteFolder)
		{
			this.path = path;
			this.name = System.IO.Path.GetFileName(this.path);
			this.remoteFolder = remoteFolder;
		}

		internal string ExternalPropertyValue
		{
			get { return this.externalPropertyValue; }
			set { this.externalPropertyValue = value; }
		}

		internal IRemoteFolder RemoteFolder
		{
			get { return this.remoteFolder; }
		}

		public void AddExternal(IExternal external)
		{
			this.externals.Add(external);
			ExternalAdded(this, new ExternalEventArgs(external));
		}

		public void FireChanged()
		{
			Changed(this, new ProjectEventArgs(this));
		}

		public void RemoveExternal(IExternal external)
		{
			this.externals.Remove(external);
			ExternalRemoved(this, new ExternalEventArgs(external));
		}

		public void UpdateExternalPropertyValue()
		{
			var builder = new StringBuilder();
			foreach (IExternal external in this.externals)
			{
				builder.AppendLine(external.Definition);
			}
			this.externalPropertyValue = builder.ToString();
		}

		#region IProject Members

		public event ExternalEventHandler ExternalAdded = delegate { };
		public event ExternalEventHandler ExternalRemoved = delegate { };

		public string Path
		{
			get { return this.path; }
		}

		public ReadOnlyCollection<IExternal> Externals
		{
			get { return new ReadOnlyCollection<IExternal>(this.externals); }
		}

		public string Name
		{
			get { return this.name; }
		}

		public Uri Url
		{
			get { return this.remoteFolder.Url; }
		}

		public bool IsUpToDate
		{
			get
			{
				if (this.localRevision < this.remoteFolder.Revision)
				{
					return false;
				}
				return this.isUpToDate;
			}
			internal set { this.isUpToDate = value; }
		}

		public event ProjectEventHandler Changed = delegate { };

		public long LocalRevision
		{
			get { return this.localRevision; }
			internal set { this.localRevision = value; }
		}

		public long RemoteRevision
		{
			get { return this.remoteFolder.Revision; }
		}

		#endregion

		#region IRemoteConnected Members

		string IRemoteConnected.Id
		{
			get { return this.path; }
		}

		IRemoteFolder IRemoteConnected.RemoteFolder
		{
			get { return this.remoteFolder; }
		}

		#endregion
	}
}